<template>
  <Transition name="slide">
    <draggable
      v-if="show"
      v-model="groupData"
      :force-fallback="true"
      :group="{ name: 'dragArea', pull: 'clone', put: false }"
      item-key="id"
      handle=".drag-handle-all"
      :disabled="!tableData.length"
      :fallback-class="'group-drag-fallback'"
    >
      <template #item>
        <div class="wrapper-container">
          <div class="drag-handle-all" :class="{ disabled: !tableData.length }">
            <i class="iconfont">&#xe7dc;</i>
            <span class="count" v-if="tableData.length">{{ tableData.length }}</span>
          </div>
          <div class="page-sort-container">
            <el-button v-if="tableData.length" class="clear-btn" type="danger" size="small" @click="handleClearClick">清空暂存区</el-button>
            <draggable
              v-model="tableData"
              animation="180"
              tag="div"
              item-key="id"
              drag-class="drag-class"
              ghost-class="ghost-class"
              :force-fallback="true"
              group="dragArea"
              class="list-container page-sort-list"
            >
              <template #item="{ element, index }">
                <div class="drag-item">
                  <div class="item-index">{{ index + 1 }}</div>
                  <div class="item-title">{{ element.title }}</div>
                  <div class="item-publisher">{{ element.publish_user_id }}</div>
                  <div class="item-time">{{ element.create_time }}</div>
                  <el-button class="delete-btn" type="danger" :icon="Delete" circle size="small" @click.stop="handleDeleteItem(index)" />
                </div>
              </template>
            </draggable>
          </div>
        </div>
      </template>
    </draggable>
  </Transition>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue'
import draggable from 'vuedraggable'
import { ElMessageBox } from 'element-plus'
import { Delete } from '@element-plus/icons-vue'

const props = defineProps({
  show: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits(['update:show', 'handleClear'])

const show = computed({
  get() {
    return props.show
  },
  async set(val) {
    emit('update:show', val)
  }
})

const tableData = ref([])
const groupData = ref([{ id: 999999, content: tableData.value, isPageSort: true }])

// 只需保持 groupData 和 tableData 的同步
watch(
  tableData,
  newVal => {
    groupData.value[0].content = structuredClone(newVal)
  },
  { deep: true }
)

defineExpose({
  tableData
})

// 但需要在 mounted 时设置拖拽时显示的数量
onMounted(() => {
  const style = document.createElement('style')
  style.textContent = `
    .group-drag-fallback[data-count]::after {
      content: attr(data-count);
    }
  `
  document.head.appendChild(style)
})

const handleClearClick = async () => {
  try {
    await ElMessageBox.confirm('确认清空暂存区内容吗？', '提示', {
      confirmButtonText: '确认',
      cancelButtonText: '取消',
      type: 'warning'
    })
    handleClear()
  } catch {
    return
  }
}

const handleClear = () => {
  tableData.value = []
  emit('handleClear')
}

const handleDeleteItem = index => {
  tableData.value.splice(index, 1)
}
</script>

<style lang="scss" scoped>
.wrapper-container {
  display: flex;
  align-items: center;
  gap: 12px;
}

.drag-handle-all {
  width: 24px;
  height: 200px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  color: #909399;
  cursor: move;

  &:hover {
    color: #409eff;
  }

  &.disabled {
    cursor: not-allowed;
    color: #c0c4cc;

    &:hover {
      color: #c0c4cc;
    }
  }

  i {
    font-size: 20px;
  }

  .count {
    font-size: 12px;
    background: #f4f4f5;
    color: #909399;
    min-width: 16px;
    height: 16px;
    line-height: 16px;
    text-align: center;
    border-radius: 8px;
    padding: 0 4px;
  }
}

.page-sort-container {
  position: relative;
  flex: 1;
  min-height: 100px;
  max-height: 200px;
  background: #fff;
  border: 2px dashed #e4e7ed;
  border-radius: 4px;
  padding: 16px;
  overflow-y: auto;

  &:hover {
    border-color: #c0c4cc;
  }
}

.list-container {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 100px;
  height: 100%;
  padding: 4px;

  &:empty {
    &::after {
      content: '拖拽内容到这里';
      display: flex;
      align-items: center;
      justify-content: center;
      height: 100%;
      color: #909399;
      font-size: 14px;
    }
  }
}

.drag-item {
  display: flex;
  align-items: center;
  height: 36px;
  padding: 0 12px;
  background: #fff;
  border-radius: 4px;
  border: 1px solid #e4e7ed;
  font-size: 12px;
  color: #606266;
  cursor: move;

  &:hover {
    border-color: #409eff;

    .delete-btn {
      opacity: 1;
    }
  }

  .item-index {
    width: 60px;
  }

  .item-title {
    flex: 1;
    padding-right: 20px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .item-publisher {
    width: 120px;
  }

  .item-time {
    width: 180px;
  }

  .delete-btn {
    opacity: 0;
    transition: opacity 0.2s ease;
    margin-left: 8px;
  }
}

.drag-class {
  background-color: #fff;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  opacity: 0.8;
  border: 1px dashed #409eff;
}

.ghost-class {
  background: #f5f7fa;
  border: 1px dashed #e4e7ed;
  opacity: 0.8;
}

.group-drag-fallback {
  background: #fff;
  border-radius: 4px;
  padding: 8px 12px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: #606266;

  &::before {
    content: '内容组';
  }

  &::after {
    content: attr(data-count);
    background: #f4f4f5;
    color: #909399;
    font-size: 12px;
    min-width: 16px;
    height: 16px;
    line-height: 16px;
    text-align: center;
    border-radius: 8px;
    padding: 0 4px;
  }
}

.slide-enter-active,
.slide-leave-active {
  transition: all 0.3s ease;
}

.slide-enter-from,
.slide-leave-to {
  opacity: 0;
}

.clear-btn {
  position: absolute;
  right: 20px;
  top: 0;
  z-index: 1;
}
</style>
